<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <meta name="renderer" content="webkit">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <link rel="dns-prefetch" href="http://jxpxxzj.oschina.io">
  <title>Private-Cloud-Music 的前端实现 | 雄心万丈, 躺在床上</title>
  <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">
  <meta name="description" content="序被安利了 https://github.com/BLumia/Private-Cloud-Music, 虽然我没有这个需求(网易云已经解决了这个问题), 不过由于正在考虑玩玩 React, 所以决定重写一个这个前端用来学习 React 和练手.
为什么选择 React在网页设计大赛的文章里提到了为什么选择 Vue 而不是 React, 主要的原因是不喜欢 jsx 的奇葩语法. 这次技术选型则转到">
<meta property="og:type" content="article">
<meta property="og:title" content="Private-Cloud-Music 的前端实现">
<meta property="og:url" content="http://jxpxxzj.oschina.io/2017/02/12/impl-pcm-fe/index.html">
<meta property="og:site_name" content="雄心万丈, 躺在床上">
<meta property="og:description" content="序被安利了 https://github.com/BLumia/Private-Cloud-Music, 虽然我没有这个需求(网易云已经解决了这个问题), 不过由于正在考虑玩玩 React, 所以决定重写一个这个前端用来学习 React 和练手.
为什么选择 React在网页设计大赛的文章里提到了为什么选择 Vue 而不是 React, 主要的原因是不喜欢 jsx 的奇葩语法. 这次技术选型则转到">
<meta property="og:image" content="http://jxpxxzj.oschina.io/2017/02/12/impl-pcm-fe/1.png">
<meta property="og:updated_time" content="2017-02-13T05:33:40.574Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Private-Cloud-Music 的前端实现">
<meta name="twitter:description" content="序被安利了 https://github.com/BLumia/Private-Cloud-Music, 虽然我没有这个需求(网易云已经解决了这个问题), 不过由于正在考虑玩玩 React, 所以决定重写一个这个前端用来学习 React 和练手.
为什么选择 React在网页设计大赛的文章里提到了为什么选择 Vue 而不是 React, 主要的原因是不喜欢 jsx 的奇葩语法. 这次技术选型则转到">
<meta name="twitter:image" content="http://jxpxxzj.oschina.io/2017/02/12/impl-pcm-fe/1.png">
  
    <link rel="alternative" href="/atom.xml" title="雄心万丈, 躺在床上" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  <link rel="stylesheet" href="/main.css?v=4.0.0.css">
  
  
</head></html>
<body>
  <div id="container" q-class="show:isCtnShow">
    <canvas id="anm-canvas" class="anm-canvas"></canvas>
    <div class="left-col" q-class="show:isShow">
      <div class="overlay"></div>
<div class="intrude-less">
	<header id="header" class="inner">
		<a href="/" class="profilepic">
			<img src="https://en.gravatar.com/userimage/114716744/58f3842dbf28498a4087b85f00b33de4.jpg?size=300" class="js-avatar">
		</a>

		<hgroup>
		  <h1 class="header-author"><a href="/">jxpxxzj</a></h1>
		</hgroup>

		
		<p class="header-subtitle">我们最怕看到的未来是, 我们不守规矩, 以为这是聪明, 是特权, 是优越感。</p>
		

		<nav class="header-menu">
			<ul>
			
				<li><a href="/">主页</a></li>
	        
				<li><a href="/categories/随笔/">随笔</a></li>
	        
				<li><a href="/categories/技术/">技术</a></li>
	        
			</ul>
		</nav>
		<nav class="header-smart-menu">
	        
    		
    			
            
    			
            
    			
            
		</nav>
		<nav class="header-nav">
			<div class="social">
				
					<a class="github" target="_blank" href="https://github.com/jxpxxzj" title="github"><i class="icon-github"></i></a>
		        
					<a class="weibo" target="_blank" href="http://weibo.com/jxpxxzj" title="weibo"><i class="icon-weibo"></i></a>
		        
					<a class="rss" target="_blank" href="/atom.xml" title="rss"><i class="icon-rss"></i></a>
		        
					<a class="zhihu" target="_blank" href="https://www.zhihu.com/people/zijin-xiao" title="zhihu"><i class="icon-zhihu"></i></a>
		        
					<a class="mail" target="_blank" href="mailto:ZijinX@outlook.com" title="mail"><i class="icon-mail"></i></a>
		        
			</div>
		</nav>
	</header>		
</div>
    </div>
    <div class="mid-col" q-class="show:isShow,hide:isShow|isFalse">
      <nav id="mobile-nav">
  	<div class="overlay">
  		<div class="slider-trigger"><i class="icon-sort"></i></div>
  		<h1 class="header-author js-mobile-header hide">jxpxxzj</h1>
  	</div>
	<div class="intrude-less">
		<header id="header" class="inner">
			<div class="profilepic">
				<img src="https://en.gravatar.com/userimage/114716744/58f3842dbf28498a4087b85f00b33de4.jpg?size=300" class="js-avatar">
			</div>
			<hgroup>
			  <h1 class="header-author">jxpxxzj</h1>
			</hgroup>
			
			<p class="header-subtitle">我们最怕看到的未来是, 我们不守规矩, 以为这是聪明, 是特权, 是优越感。</p>
			
			<nav class="header-menu">
				<ul>
				
					<li><a href="/">主页</a></li>
		        
					<li><a href="/categories/随笔/">随笔</a></li>
		        
					<li><a href="/categories/技术/">技术</a></li>
		        
		        
				</ul>
			</nav>
			<nav class="header-nav">
				<div class="social">
					
						<a class="github" target="_blank" href="https://github.com/jxpxxzj" title="github"><i class="icon-github"></i></a>
			        
						<a class="weibo" target="_blank" href="http://weibo.com/jxpxxzj" title="weibo"><i class="icon-weibo"></i></a>
			        
						<a class="rss" target="_blank" href="/atom.xml" title="rss"><i class="icon-rss"></i></a>
			        
						<a class="zhihu" target="_blank" href="https://www.zhihu.com/people/zijin-xiao" title="zhihu"><i class="icon-zhihu"></i></a>
			        
						<a class="mail" target="_blank" href="mailto:ZijinX@outlook.com" title="mail"><i class="icon-mail"></i></a>
			        
				</div>
			</nav>
		</header>				
	</div>
</nav>
      <div id="wrapper" class="body-wrap">
        <div class="menu-l">
          <div class="canvas-wrap">
            <canvas data-colors="#eaeaea" data-sectionheight="100" data-contentid="js-content" id="myCanvas1" class="anm-canvas"></canvas>
          </div>
          <div id="js-content" class="content-ll">
            <article id="post-impl-pcm-fe" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-inner">
    
      <header class="article-header">
        <h1 class="article-title" itemprop="name">
      Private-Cloud-Music 的前端实现
    </h1>
        <a href="/2017/02/12/impl-pcm-fe/" class="archive-article-date">
  	<time datetime="2017-02-12T14:47:33.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2017-02-12</time>
</a>
      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <h2 id="序"><a href="#序" class="headerlink" title="序"></a>序</h2><p>被安利了 <a href="https://github.com/BLumia/Private-Cloud-Music" target="_blank" rel="external">https://github.com/BLumia/Private-Cloud-Music</a>, 虽然我没有这个需求(网易云已经解决了这个问题), 不过由于正在考虑玩玩 React, 所以决定重写一个这个前端用来学习 React 和练手.</p>
<h2 id="为什么选择-React"><a href="#为什么选择-React" class="headerlink" title="为什么选择 React"></a>为什么选择 React</h2><p>在网页设计大赛的文章里提到了为什么选择 Vue 而不是 React, 主要的原因是不喜欢 jsx 的奇葩语法. 这次技术选型则转到了 React, 除了慢慢接受 jsx, 还有几个原因是踩了 Vue 的坑.</p>
<p>先贴个轮子哥语录:<br><img src="/2017/02/12/impl-pcm-fe/1.png" alt="1.png" title=""><br>放到这里的原因是转到 React 完美的符合了 “什么都不管, 先做出来” 的这种理念.  </p>
<h3 id="踩了什么坑"><a href="#踩了什么坑" class="headerlink" title="踩了什么坑"></a>踩了什么坑</h3><h4 id="Vue"><a href="#Vue" class="headerlink" title="Vue"></a>Vue</h4><p>踩坑要从技术专家考核作品说起, 在作品中为了实现每个文件一个进度条, 需要给每个 object 都挂一个 <code>progress</code> 的 key, 而 Vue 不允许动态添加根级响应式属性, 所以必须在初始化实例前声明根级响应式属性, 最后的方案是对后端 API 进行改动, 将一个 <code>progress</code> 夹在后端的数据中传给前端处理.<br>这明显是一种很 hack 的设计, 不过为了解决问题, 也只能这样处理. React 的单向数据流在这种问题上还是有一定优势的.</p>
<p>然后就是生命周期了, 有时候想让 Vue 重绘一下, 或者不想让 Vue 重绘, 但是并不知道怎么搞…<br>用前端框架的时候还想着操作 dom, 绝大多数情况是方法不对, 既然我都找不到方法, 那我还是先放一放跳个新坑好了.</p>
<h4 id="Element-UI"><a href="#Element-UI" class="headerlink" title="Element-UI"></a>Element-UI</h4><p>Element-UI 做的还是可以的, 但是在 Layout, 以及设计语言等方面则有明显的不足, 同时小问题也比较多, Ant Design 很好的解决了这两个痛点问题, 虽然不像 Vue 的坑那么影响, 但是也是推动选择 React 的一大因素.</p>
<h2 id="开发经历"><a href="#开发经历" class="headerlink" title="开发经历"></a>开发经历</h2><h3 id="React-Antd-的配置"><a href="#React-Antd-的配置" class="headerlink" title="React + Antd 的配置"></a>React + Antd 的配置</h3><p>Vue 的环境配置其实是非常简单的, 现在的几个 Vue 项目的环境都是手动搭建的, 没有使用脚手架 / CLI 之类的工具辅助完成.</p>
<p>但是换到 React 之后, 手动搭建环境的这件事就很惨烈的失败了, 最后依靠 antd-init 完成了初始化工作, 然后自己加上 ESLint 之类的辅助工具.<br>主要的问题还是 webpack2, babel 等搞起来让我很头大, 因为需要配置 jsx 翻译等, webpack2 的 API 又有些改动, 参考文档偏少, 同时 Antd 还需要依赖一些 plugins 用于选择性加载组件等功能, 全凑一起之后各种小问题大问题, 不过我还是会找个时间研究下如何手动搭建环境的.<br>Antd 还提供了一些别的脚手架, 用起来让我感觉更是困惑, antd-init 还是比较快捷的, 毕竟也不是什么大项目, 用这种简单粗暴的工具应该不是什么问题, 但是之后的应用程序设计竞赛, 估计还是得找个适合大型前端项目用的管理工具了.</p>
<h3 id="编码实践"><a href="#编码实践" class="headerlink" title="编码实践"></a>编码实践</h3><p>开始编写之前, 先是通读了一遍 React 的官方文档, 理清了一些语法上的问题之后, 之后就开始动手编写代码. </p>
<h4 id="理解-React"><a href="#理解-React" class="headerlink" title="理解 React"></a>理解 React</h4><p>这是第一次写 React, React 使用的是 Functional-Programming 的理念, 以前在研究 Haskell 的时候接触过一些, 但是理解的不够深入.<br>官方的 thinking-in-react 那页看完之后估计是全忘了, 尤其是如何抽象组件和完成通信, 写出来的东西是一大坨非常复杂的 elements, 反正看起来是非常丑, 也似乎有点难维护. 虽然可以正常工作. 应该要找时间重读一遍, 然后重构一下的.</p>
<h4 id="接受-jsx"><a href="#接受-jsx" class="headerlink" title="接受 jsx"></a>接受 jsx</h4><p>有人说对于一个新东西不要马上一巴掌拍死, 怎么着也给个 5 分钟, 第一次见到 jsx 是没给这 5 分钟直接贴了个反人类的标签的, 但是当我重新开始考虑 React 时, jsx 用自己 NB 的表现在我的心中重新树立了光辉的形象.<br>jsx 是那种看起来乱, 写起来比较爽的东西, 在 html 中任意插入 js 给了这种表达方式无穷无尽的可能性, 而且特别好理解, Vue 中则是通过 <code>:</code> ,<code>v-bind</code> 等完成的这些工作, 没有 React 的 <code>{ }</code> 搞定一切的这种快感.<br>当然也有不足, 比如占用 <code>class</code> 然后需要用 <code>className</code> 替代, 和 <code>style</code> 中的驼峰命名法等, 但是这些小问题掩盖不了任意插入 js 的这个爽到不行的 feature.</p>
<h4 id="开发体验和组件库"><a href="#开发体验和组件库" class="headerlink" title="开发体验和组件库"></a>开发体验和组件库</h4><p>写的时候, 慢慢的有了一种在写 WPF 的熟悉感, 通过一些结构化的描述语言描述界面, 然后绑定事件到方法, 由方法去设置 state, 然后关联到组件渲染上, 思维上非常自然, 不得不说 React 的设计精巧.<br>使用 vue-desktop-framework 开发的时候, 也有一种类似的感觉, 但是总没有 React 这么干净和利落, 所以是不是应该搞一个 react-desktop-framework ?<br>Antd 提供了非常丰富的组件, 也有很灵活的事件, 各种需求在查过文档后都能很快的实现出来, Element-UI 的文档看着就是有那么一点点的难受, 想做个什么东西却找不到合适的例子可以参考.</p>
<h4 id="使用-lt-Menu-gt-全家桶"><a href="#使用-lt-Menu-gt-全家桶" class="headerlink" title="使用 &lt;Menu&gt; 全家桶"></a>使用 <code>&lt;Menu&gt;</code> 全家桶</h4><p>首先实现的需求是显示文件夹列表,使用的组件是 <code>&lt;SubMenu&gt;</code> 和 <code>&lt;Menu.Item&gt;</code> 此处 Antd 有一个坑, 在列表太长时并不能滚动菜单, 导致的结果是移动端横屏状态下特别难受.<br>其次是折叠和展开. 折叠和展开的设计在 网易云音乐 UWP 中有一个很好的实践, 展开时显示所有歌单, 折叠时只显示几个主要功能按钮, 点击后展开列表并跳转到对应功能. 这个 Menu 的实现模仿了这一设计.<br>目前未解决的 bug 是点击 Settings 后当前文件夹的蓝色高亮会消失.</p>
<h4 id="列表渲染与条件渲染"><a href="#列表渲染与条件渲染" class="headerlink" title="列表渲染与条件渲染"></a>列表渲染与条件渲染</h4><p>条件渲染上, Vue 使用的是把 <code>v-if</code> 写在 attribute 的这种形式, 比较直观, 但是有时候会引起一点困惑, 尤其是混杂了复杂的 js 表达式时.<br>React 使用了一种有点费解但是很合理的方式, 体现了 jsx 中 html node 的表达式性质:<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">&#123; <span class="keyword">this</span>.state.visible &amp;&amp; &lt;node /&gt;&#125;</div></pre></td></tr></table></figure></p>
<p>这样 <code>&lt;node /&gt;</code> 就会在 <code>this.state.visible</code> 为真时渲染, 也可以直接混入一个 if 语句然后实现条件渲染.</p>
<p>列表渲染 Vue 使用的也是 <code>v-for</code> 挂到一个数组上的 attribute, 和条件渲染一样直观但是也会有一些困惑.<br>React 需要用 <code>Array.map</code> 等方式进行处理, 或者使用 <code>Array.push</code> 创建节点数组再插入 dom 实现, 其实像我这种比较习惯用代码控制界面的, 这种方式会显得更亲切一点.<br>然而用得不好还是会炸, 参见下面的失败尝试.  </p>
<h4 id="lt-input-gt-的新使用方法"><a href="#lt-input-gt-的新使用方法" class="headerlink" title="&lt;input&gt; 的新使用方法"></a><code>&lt;input&gt;</code> 的新使用方法</h4><p>Vue 中的双向绑定是非常好理解 <code>&lt;input&gt;</code> 是如何工作的, 在数据改动的时候, <code>v-bind</code> 到的 store state 也会跟着变动.<br>React 的单向数据流是没法像这样工作的, 需要在 <code>onChange</code> 属性中使用 <code>this.setState</code> 改动 state, <code>&lt;input&gt;</code> 才会改变. <code>onChange</code> 是 React 添加的一个 event handler.<br>在实现可拖拽的进度条控制音乐播放进度中, 使用了这种方法实现播放进度的控制. 这个进度条操作上实现的非常漂亮, 较原前端更直观和简便, 一点遗憾就是不能显示缓冲进度.</p>
<h4 id="关于-lt-Modal-gt-和-Settings-的实现"><a href="#关于-lt-Modal-gt-和-Settings-的实现" class="headerlink" title="关于 &lt;Modal&gt; 和 Settings 的实现"></a>关于 <code>&lt;Modal&gt;</code> 和 Settings 的实现</h4><p><code>&lt;Modal&gt;</code> 的问题主要是两个, 其一是如何在取消时不改变原有配置, 其二是在每次打开 Settings 时创建不同的 <code>&lt;Modal&gt;</code>实例.<br>前者通过临时 state 过渡, 在 Cancel 时将临时 state 的值还原, Ok 则将临时 state 的值复制给配置项; 后者则在 <code>setState</code> 时传入一个随机数作为 key, 这种方法在 Antd 的文档中提到过.</p>
<h4 id="axios-的体验与后端-API-设计"><a href="#axios-的体验与后端-API-设计" class="headerlink" title="axios 的体验与后端 API 设计"></a>axios 的体验与后端 API 设计</h4><p>axios 的体验非常类似 vue-resource, 扫一遍文档即可快速上手, 同时也相对独立, 可以很好地整合进代码中.<br>后端 API 上是被坑了一下, 阅读后端文档时给出了两个参数, 然后往后端直接塞了一个 json, 结果一直是 illegal, 困惑的看了一下原前端实现, 发现是用 &amp; 连接参数…<br>个人认为直接传一个 key-value 形式的 json 应该是更科学的方式, 微信公众平台开发文档使用的就是这种形式.<br>还有一个比较神奇的是 Postman 给出的 http status code 始终是 200, 但是 body 中各种各样的 code 都有, 从200 到 404, 应该是后端的 bug.</p>
<h4 id="编写组件的失败尝试"><a href="#编写组件的失败尝试" class="headerlink" title="编写组件的失败尝试"></a>编写组件的失败尝试</h4><p>个人认为是对 React 的认识不够深入…<br>尝试编写了如下组件:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="comment">// Hightlight.js 似乎无法正确显示 jsx 的代码高亮, 请自行脑补.</span></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">fMenu</span>(<span class="params">props</span>) </span>&#123;</div><div class="line">     <span class="keyword">return</span> &lt;Menu.Item key=&#123;props.text&#125;&gt;&#123;props.text&#125;&lt;/Menu.Item&gt;;</div><div class="line">&#125;</div><div class="line">function fMenuList(props) &#123;</div><div class="line">    let rows = [];</div><div class="line">    for(let i = 0; i &lt; props.fdlist.length; i++)</div><div class="line">        rows.push(&lt;fMenu text=&#123;props.fdlist[i]&#125; /&gt;);</div><div class="line">    return rows;</div><div class="line">&#125;</div><div class="line">/// ... 此处省略其他语句和节点</div><div class="line">&lt;fMenuList fdlist=&#123;this.state.fdlist&#125; /&gt;</div></pre></td></tr></table></figure>
<p>然后莫名奇妙的就炸了…<br>替代方法如下, 似乎是一种更合理的选择?<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">&#123;<span class="keyword">this</span>.state.fdlist.map(<span class="function"><span class="params">x</span> =&gt;</span> &lt;Menu.Item key=&#123;x&#125;&gt;&#123;x&#125;&lt;<span class="regexp">/Menu.Item&gt;)&#125;</span></div></pre></td></tr></table></figure></p>
<h2 id="祭"><a href="#祭" class="headerlink" title="祭"></a>祭</h2><p><a href="https://github.com/BearKidsTeam/private-music-react" target="_blank" rel="external">https://github.com/BearKidsTeam/private-music-react</a> // 丑到不行的代码</p>
      

      
    </div>
    <div class="article-info article-info-index">
      
      <div class="article-tag tagcloud">
		<i class="icon-price-tags"></i>
		<ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/React/">React</a></li><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/前端/">前端</a></li></ul>
	</div>
      <div class="article-category tagcloud">
	<i class="icon-book icon"></i>
	<a class="article-category-link" href="/categories/技术/">技术</a>
	</div>
      

      
        <div class="share-btn share-icons tooltip-left">
  <div class="tooltip tooltip-east">
    <span class="tooltip-item">
      <a href="javascript:;" class="share-sns share-outer">
        <i class="icon icon-share"></i>
      </a>
    </span>
    <span class="tooltip-content">
      <div class="share-wrap">
        <div class="share-icons">
          <a class="weibo share-sns" href="javascript:;" data-type="weibo">
            <i class="icon icon-weibo"></i>
          </a>
          <a class="weixin share-sns wxFab" href="javascript:;" data-type="weixin">
            <i class="icon icon-weixin"></i>
          </a>
          <a class="qq share-sns" href="javascript:;" data-type="qq">
            <i class="icon icon-qq"></i>
          </a>
          <a class="douban share-sns" href="javascript:;" data-type="douban">
            <i class="icon icon-douban"></i>
          </a>
          <a class="qzone share-sns" href="javascript:;" data-type="qzone">
            <i class="icon icon-qzone"></i>
          </a>
          <a class="facebook share-sns" href="javascript:;" data-type="facebook">
            <i class="icon icon-facebook"></i>
          </a>
          <a class="twitter share-sns" href="javascript:;" data-type="twitter">
            <i class="icon icon-twitter"></i>
          </a>
          <a class="google share-sns" href="javascript:;" data-type="google">
            <i class="icon icon-google"></i>
          </a>
        </div>
      </div>
    </span>
  </div>
</div>

<div class="page-modal wx-share js-wx-box">
    <a class="close js-modal-close" href="javascript:;"><i class="icon icon-close"></i></a>
    <p>扫一扫，分享到微信</p>
    <div class="wx-qrcode">
      <img src="http://s.jiathis.com/qrcode.php?url=http://jxpxxzj.oschina.io/2017/02/12/impl-pcm-fe/" alt="微信分享二维码">
    </div>
</div>

<div class="mask js-mask"></div>
      
      <div class="clearfix"></div>
    </div>
  </div>
</article>

  <nav id="article-nav">
  
    <a href="/2017/02/26/after-first-check/" id="article-nav-newer" class="article-nav-link-wrap">
      <i class="icon-circle-left"></i>
      <div class="article-nav-title">
        
          瞎扯集 \#1
        
      </div>
    </a>
  
  
    <a href="/2016/12/24/softcsu-website/" id="article-nav-older" class="article-nav-link-wrap">
      <div class="article-nav-title">网页设计大赛记录</div>
      <i class="icon-circle-right"></i>
    </a>
  
</nav>





<div class="duoshuo">
	<!-- 多说评论框 start -->
	<div class="ds-thread" data-thread-key="impl-pcm-fe" data-title="Private-Cloud-Music 的前端实现" data-url="http://jxpxxzj.oschina.io/2017/02/12/impl-pcm-fe/"></div>
	<!-- 多说评论框 end -->
	<!-- 多说公共JS代码 start (一个网页只需插入一次) -->
	<script type="text/javascript">
	var duoshuoQuery = {short_name:"jxgithub"};
	(function() {
		var ds = document.createElement('script');
		ds.type = 'text/javascript';ds.async = true;
		ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
		ds.charset = 'UTF-8';
		(document.getElementsByTagName('head')[0] 
		 || document.getElementsByTagName('body')[0]).appendChild(ds);
	})();
	</script>
	<!-- 多说公共JS代码 end -->
</div>
          </div>
        </div>
      </div>
      <footer id="footer">
  <div class="outer">
    <div id="footer-info">
    	<div class="footer-left">
    		&copy; 2017 jxpxxzj
    	</div>
      	<div class="footer-right">
      		<a href="http://hexo.io/" target="_blank">Hexo</a>  Theme <a href="https://github.com/litten/hexo-theme-yilia" target="_blank">Yilia</a> by Litten
      	</div>
    </div>
  </div>
</footer>
    </div>
    <script>
	var yiliaConfig = {
		mathjax: true,
		isHome: false,
		isPost: true,
		isArchive: false,
		isTag: false,
		isCategory: false,
		open_in_new: true,
		root: "/",
		innerArchive: false
	}
</script>

<script src="/./main.js?v=4.0.0.js"></script>


<script type="text/x-mathjax-config">
MathJax.Hub.Config({
    tex2jax: {
        inlineMath: [ ['$','$'], ["\\(","\\)"]  ],
        processEscapes: true,
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
    }
});

MathJax.Hub.Queue(function() {
    var all = MathJax.Hub.getAllJax(), i;
    for(i=0; i < all.length; i += 1) {
        all[i].SourceElement().parentNode.className += ' has-jax';                 
    }       
});
</script>

<script src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
    <div class="tools-col" q-class="show:isShow,hide:isShow|isFalse" q-on="click:stop(e)">
  <div class="tools-wrap">
    

    

    
  </div>
  
</div>
    <!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>

    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">

        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                <!--  Controls are self-explanatory. Order can be changed. -->

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" style="display:none" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                      <div class="pswp__preloader__cut">
                        <div class="pswp__preloader__donut"></div>
                      </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div> 
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div>
  </div>
</body>
